package net.chowda.castcluster;

import net.chowda.castcluster.util.CastClusterConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * any source we want to subscribe to and/or get videos from needs to impement this abstract class
 *
 * this was some of the first stuff I experimented with and I really dislike the API.. it is
 * slowing going to change to only direcly expose VideoSource fetching methods.
 *
 * I don't think I like the static methods either....
 *
 * User: dbachelder
 */
public abstract class VideoProvider {
    Map<String, String> properties = new HashMap<String, String>();

    public static List<Video> getVideos(String url) {
        return getProvider(url).getProviderVideos(url);
    }

    /**
     * check each provider to see if it wants to do something with this URL.
     *
     * all sources are added to the returned list
     */
    public static List<VideoSource> getSourcesForWebUrl(String url) {
        List<VideoSource> sources = new ArrayList<VideoSource>(2);

        CastClusterConfig config = CastClusterConfig.getInstance();
        for (VideoProvider videoProvider : config.getProviders()) {
            sources.addAll(videoProvider.getProviderSourcesForWebUrl(url));
        }
        return sources;
    }

    public static VideoSource getSourceForCCUrl(String url) {
        return getProvider(url).getProviderSourceForCCUrl(url);
    }

    public static String fetchVideo(String url) {
        return getProvider(url).fetchProviderVideo(url);
    }
    
    public static String getFeed(String url) {
        return getProvider(url).getProviderFeed(url);
    }

    public static void cleanupAfterFetch(String videoUrl) {
        getProvider(videoUrl).providerCleanupAfterFetch(videoUrl);
    }

    public abstract String getProviderFeed(String url);
    public abstract List<Video> getProviderVideos(String url);
    public abstract String fetchProviderVideo(String url);
    public abstract VideoSource getProviderSourceForCCUrl(String url);
    public abstract void providerCleanupAfterFetch(String url);

    // WORK IN PROGRESS.... this whole idea... working on it.
    public abstract List<VideoSource> getProviderSourcesForWebUrl(String url);

    private static VideoProvider getProvider(String url) {
        Map<String, VideoProvider> map = CastClusterConfig.getInstance().getProviderMap();
        String[] strings = url.split("\\|");
        VideoProvider videoProvider = map.get(strings[0]);
        if(videoProvider == null) {
            StringBuilder build = new StringBuilder(256);
            build.append("can't find provider for URL: ").append(url);
            build.append("\navailable providers:\n");
            for (String key : map.keySet()) {
                build.append("\t").append(key).append(" = ").append(VideoProvider.class).append("\n");
            }
            throw new IllegalArgumentException(build.toString());
        }
        return videoProvider;
    }

    public Map<String, String> getProperties() {
        return properties;
    }

    public void setProperties(Map<String, String> properties) {
        this.properties = properties;
    }

    public static String getFirstMatchingGroup(String regex, String string) {
        String myMatch = null;
        if (string != null && regex != null) {
            Matcher matcher = Pattern.compile(regex).matcher(string);
            if(matcher.find() && matcher.groupCount() >= 1) {
                myMatch = matcher.group(1);
            }
        }
        return myMatch;
    }
}
